package ws

import (
	"sync"
	"github.com/gorilla/websocket"
)

type Ws链接_标识 struct {
	链接表列 map[string]map[string][]*websocket.Conn
	锁列表 map[string]map[string][]*sync.RWMutex
	读写许可 *sync.RWMutex
}

func (类 *Ws链接_标识) C初始化() {
	类.链接表列 = make(map[string]map[string][]*websocket.Conn)
	类.锁列表 =make(map[string]map[string][]*sync.RWMutex)
	var 锁 sync.RWMutex
	类.读写许可 = &锁
}

func (类 *Ws链接_标识) Z增加链接(方法名 string, 标识 string, 链接 *websocket.Conn) {
	类.读写许可.Lock()
	defer 类.读写许可.Unlock()
	if 方法列表, ok := 类.链接表列[方法名]; ok {
		if 标识列表, ok := 方法列表[标识]; ok {
			for _, v := range 标识列表 {
				if v == 链接 {
					return
				}
			}
			标识列表 = append(标识列表, 链接)
			类.链接表列[方法名][标识] = 标识列表

			锁列表:=类.锁列表[方法名][标识]
			var 锁 sync.RWMutex
			锁列表=append(锁列表, &锁)
			类.锁列表[方法名][标识]=锁列表

		} else {
			var 标识列表 = make([]*websocket.Conn, 1)
			标识列表[0] = 链接
			var 标识表= make(map[string][]*websocket.Conn)
			标识表[标识]=标识列表
			类.链接表列[方法名] = 标识表

			var 锁列表 = make([]*sync.RWMutex, 1)
			var 锁 sync.RWMutex
			锁列表[0]=&锁
			var 锁标识表= make(map[string][]*sync.RWMutex)
			锁标识表[标识]=锁列表
			类.锁列表[方法名]=锁标识表
		}

	} else {
		var 标识列表 = make([]*websocket.Conn, 1)
		标识列表[0] = 链接
		var 标识表= make(map[string][]*websocket.Conn)
		标识表[标识]=标识列表
		类.链接表列[方法名] = 标识表

		var 锁列表 = make([]*sync.RWMutex, 1)
		var 锁 sync.RWMutex
		锁列表[0]=&锁
		var 锁标识表= make(map[string][]*sync.RWMutex)
		锁标识表[标识]=锁列表
		类.锁列表[方法名]=锁标识表
	}
	

}

func (类 *Ws链接_标识) S删链接(方法名 string, 标识 string, 链接 *websocket.Conn) {
	类.读写许可.Lock()
	defer 类.读写许可.Unlock()
	if 标识列表, ok := 类.链接表列[方法名][标识]; ok {
		for i, v := range 标识列表 {
			if v == 链接 {
				标识列表 = append(标识列表[:i], 标识列表[i+1:]...)
				类.链接表列[方法名][标识] = 标识列表
				
				锁表:=类.锁列表[方法名][标识]
				锁表 = append(锁表[:i], 锁表[i+1:]...)
				类.锁列表[方法名][标识]=锁表
				return
			}
		}
	}

}

func (类 *Ws链接_标识) T推送消息_文本(方法名 string, 消息 string, 标识 string) {
	类.读写许可.RLock()
	defer 类.读写许可.RUnlock()
	if 标识列表, ok := 类.链接表列[方法名][标识]; ok {
		for i, v := range 标识列表 {
			锁:=类.锁列表[方法名][标识][i]
			go 推送消息(v,锁,消息)

		}

	}

}

func (类 *Ws链接_标识) T推送消息_文本_多标识(方法名 string, 消息 string, 标识组 ...string) {
	类.读写许可.RLock()
	defer 类.读写许可.RUnlock()
	for _, 标识 := range 标识组 {
		if 标识列表, ok := 类.链接表列[方法名][标识]; ok {
			for i, v := range 标识列表 {
				锁:=类.锁列表[方法名][标识][i]
				go 推送消息(v,锁,消息)
				//go v.WriteMessage(websocket.TextMessage, []byte(消息))

			}

		}

	}

}

func (类 *Ws链接_标识) T推送消息_方法推文本(方法名 string, 消息方法 func() string, 标识 string) {
	类.读写许可.RLock()
	defer 类.读写许可.RUnlock()
	发送消息 := 消息方法()
	if 标识列表, ok := 类.链接表列[方法名][标识]; ok {
		for i, v := range 标识列表 {
			锁:=类.锁列表[方法名][标识][i]
			go 推送消息(v,锁,发送消息)
			//go v.WriteMessage(websocket.TextMessage, []byte(发送消息))

		}

	}

}

func (类 *Ws链接_标识) T推送消息_方法推文本_多标识(方法名 string, 消息方法 func()string, 标识组 ...string) {
	类.读写许可.RLock()
	defer 类.读写许可.RUnlock()
	发送消息 := 消息方法()
	for _, 标识 := range 标识组 {
		if 标识列表, ok := 类.链接表列[方法名][标识]; ok {
			for i, v := range 标识列表 {
				锁:=类.锁列表[方法名][标识][i]
				go 推送消息(v,锁,发送消息)

				//go v.WriteMessage(websocket.TextMessage, []byte(发送消息))

			}

		}

	}

}

func 推送消息(链接 *websocket.Conn,锁 *sync.RWMutex,发送消息 string){
	锁.Lock()
	链接.WriteMessage(websocket.TextMessage, []byte(发送消息))
	锁.Unlock()
}
